#ifndef _FS_FILE_H
#define  _FS_FILE_H
#include "types.h"
#include "fs.h"
#include "sleeplock.h"
#include "fat32.h"
struct dirent {
    char  filename[255 + 1];
    uint8   attribute;
    uint32  first_clus;
    uint32  file_size;

    uint32  cur_clus;
    uint    clus_cnt;

    /* for OS */
    uint8   dev;
    uint8   dirty;
    uint8   valid;
    int     ref;
    uint32  off;            // offset in the parent dir entry, for writing convenience
    struct dirent *parent;  // because FAT32 doesn't have such thing like inum, use this for cache trick
    struct dirent *next;
    struct dirent *prev;
    struct sleeplock    lock;
};

struct fs_file {
  enum { FD_NONE, FD_PIPE, FD_ENTRY, FD_DEVICE } type;
  int ref; // reference count
  char readable;
  char writable;
  struct pipe *pipe; // FD_PIPE
  struct dirent *ep;
  uint off;          // FD_INODE
  short major;       // 设备编号
  short minor;       // 设备分块编号
};

#define major(dev)  ((dev) >> 16 & 0xFFFF)
#define minor(dev)  ((dev) & 0xFFFF)
#define	mkdev(m,n)  ((uint)((m)<<16| (n)))



// map major device number to device functions.
struct devsw {
    short (*open)();
    ssize_t (*read)(short, void *, size_t);
    ssize_t (*write)(short, const void *, size_t);
    void (*close)(short);
};

extern struct devsw devsw[];
struct dirent* create(char *path, short type);
struct fs_file* filealloc(void);
 int fdalloc(struct fs_file *f);
int fs_fileread(struct fs_file *f, uint64 addr, int n);
void fs_fileclose(struct fs_file *f);
struct fs_file * filedup(struct fs_file *f);
#define CONSOLE 1
#endif
